package com.lwc.cfdns.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lwc.cfdns.pojo.bo.system.MenuBO;
import com.lwc.cfdns.pojo.dto.system.MenuDTO;
import com.lwc.cfdns.pojo.entity.SystemAdmin;
import com.lwc.cfdns.pojo.entity.SystemMenu;
//import com.lwc.cfdns.pojo.vo.system.MenuOwnMetaVO;
import com.lwc.cfdns.pojo.vo.system.MenuOwnVO;
import com.lwc.cfdns.pojo.vo.system.MenuTreeVO;
import com.lwc.cfdns.pojo.vo.system.MenuVO;
import com.lwc.cfdns.service.SystemMenuService;
import com.lwc.cfdns.mapper.SystemMenuMapper;
import com.lwc.cfdns.utils.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author spring
 * @description 针对表【cfdns_system_menu(菜单权限表)】的数据库操作Service实现
 * @createDate 2023-05-23 17:02:59
 */
@Service
public class SystemMenuServiceImpl extends ServiceImpl<SystemMenuMapper, SystemMenu>
        implements SystemMenuService {

    @Autowired
    SystemAdminServiceImpl systemAdminService;

    @Autowired
    private SystemRoleMenuServiceImpl systemRoleMenuService;

    /**
     * 自动创建index,view,create,update,delete权限
     *
     * @param menu
     * @param isCreate
     * @return boolean
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/19 11:08:59
     */
//    public boolean editSubPermission(SystemMenu menu, boolean isCreate) {
//        Map<String, Map> link = new HashMap<>();
//        Map<String, String> info = new HashMap<>();
//        info.put("name", "列表");
//        info.put("method", "get");
//        link.put(menu.getName() + "/index", info);
//        Map<String, String> info1 = new HashMap<>();
//        info1.put("name", "详情");
//        info1.put("method", "get");
//        link.put(menu.getName() + "/view", info1);
//        Map<String, String> info2 = new HashMap<>();
//        info2.put("name", "创建");
//        info2.put("method", "post");
//        link.put(menu.getName() + "/create", info2);
//        Map<String, String> info3 = new HashMap<>();
//        info3.put("name", "更新");
//        info3.put("method", "put");
//        link.put(menu.getName() + "/update", info3);
//        Map<String, String> info4 = new HashMap<>();
//        info4.put("name", "删除");
//        info4.put("method", "delete");
//        link.put(menu.getName() + "/delete", info4);
//        // 删除
//        if (!isCreate) {
//            this.baseMapper.delete(new LambdaQueryWrapper<SystemMenu>().eq(SystemMenu::getPid, menu.getMenu_id()).eq(SystemMenu::getIs_curd, 2));
//        }
//        // 创建
//        if (menu.getIs_curd().equals(1)) {
//            List<SystemMenu> batchInsert = new ArrayList<>();
//            link.forEach((key, value) -> {
//                SystemMenu systemMenu = new SystemMenu();
//                systemMenu.setPid(menu.getMenu_id());
//                systemMenu.setName(key);
//                systemMenu.setPath(key);
//                systemMenu.setComponent("Layout");
//                systemMenu.setRedirect("");
//                systemMenu.setTitle(value.get("name").toString());
//                systemMenu.setMethod(value.get("method").toString());
//                systemMenu.setIcon("");
//                systemMenu.setNo_closable(2);
//                systemMenu.setBadge("");
//                systemMenu.setKeep_alive(2);
//                systemMenu.setAlways_show(2);
//                systemMenu.setHidden(2);
//                systemMenu.setTarget("");
//                systemMenu.setType(menu.getType());
//                systemMenu.setIs_menu(2);
//                systemMenu.setIs_curd(2);
//                batchInsert.add(systemMenu);
//            });
//            this.saveBatch(batchInsert);
//        }
//        return true;
//    }

    /**
     * 创建
     *
     * @param menuDTO
     * @return Map<String, Object>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/23 17:13:39
     */
    @Override
    public Map<String, Object> create(MenuDTO menuDTO) {
        Map<String, Object> map = new HashMap<>();
        SystemMenu systemMenu = new SystemMenu();
        BeanUtils.copyProperties(menuDTO, systemMenu);
        this.baseMapper.insert(systemMenu);
        //权限处理
//        systemRoleMenuService.rules(systemRole.getId(), roleDTO.getRules());
        map.put("id", systemMenu.getId());
        return map;
    }

    /**
     * 详情
     *
     * @param id
     * @return MenuVO
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/23 17:13:56
     */
    @Override
    public MenuVO view(Long id) {
        SystemMenu systemMenu = this.baseMapper.selectById(id);
        MenuVO menuVO = new MenuVO();
        BeanUtils.copyProperties(systemMenu, menuVO);
        return menuVO;
    }

    /**
     * 修改
     *
     * @param id
     * @param menuDTO
     * @return Map<String, Object>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/24 15:01:54
     */
    @Override
    public Map<String, Object> update(Long id, MenuDTO menuDTO) {
        HashMap<String, Object> map = new HashMap<>();
        SystemMenu systemMenu = this.baseMapper.selectById(id);
        BeanUtils.copyProperties(menuDTO, systemMenu, "created_at");
        systemMenu.setId(id);
        int i = this.baseMapper.updateById(systemMenu);
        // 权限处理
//        systemRoleMenuService.rules(systemRole.getId(), roleDTO.getRules());
        map.put("result", i);
        return map;
    }

    /**
     * 删除
     *
     * @param id
     * @return Map<String, Object>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/23 17:15:37
     */
    @Override
    @Transactional
    public Map<String, Object> delete(Long id) {
        HashMap<String, Object> map = new HashMap<>();
        int i = this.baseMapper.deleteById(id);
        systemRoleMenuService.deletes(id);
        map.put("result", i);
        return map;
    }

    /**
     * 列表
     *
     * @param menuBO
     * @return IPage<SystemMenu>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/24 08:20:57
     */
    @Override
    public IPage<SystemMenu> lists(MenuBO menuBO) {
        return this.baseMapper.selectPage(menuBO.toPage(), menuBO.toQueryWrapper());
    }

    /**
     * 树
     *
     * @param menuBO
     * @return List<MenuTreeVO>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/24 09:12:34
     */
    @Override
    public List<MenuTreeVO> tree(MenuBO menuBO) {
        List<SystemMenu> menus = this.baseMapper.selectList(menuBO.toQueryWrapper());
        // 转化对象
        ArrayList<MenuTreeVO> lists = new ArrayList<>();
        for (SystemMenu menu : menus) {
            MenuTreeVO menuTreeVO = new MenuTreeVO();
            menuTreeVO.setLabel(menu.getName());
            menuTreeVO.setId(menu.getId());
            menuTreeVO.setPId(menu.getPId());
            lists.add(menuTreeVO);
        }
        System.out.println(menus);
        // 转成树
        ArrayList<MenuTreeVO> trees = new ArrayList<>();
        for (MenuTreeVO list : lists) {
            if (list.getPId().equals(0l)) {
                trees.add(findChildren(lists, list));
            }
        }
        return trees;
    }

    /**
     * 我的权限菜单
     *
     * @param
     * @return List<MenuVO>
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/26 18:47:03
     */
    public List<MenuOwnVO> byown() {
        SystemAdmin systemAdmin = systemAdminService.getAdminInfo();
        List<MenuOwnVO> ownMenus = new ArrayList<>();
        List<SystemMenu> byUserIdMenuVOs = this.baseMapper.getPermissionsByUserId(systemAdmin.getId());
        // 先转化对象
        for (SystemMenu systemMenu : byUserIdMenuVOs) {
            MenuOwnVO menuOwnVO = new MenuOwnVO();
            menuOwnVO.setId(systemMenu.getId());
            menuOwnVO.setName(getRouteName(systemMenu));
            menuOwnVO.setPath(getRouterPath(systemMenu));
            menuOwnVO.setComponent(getComponent(systemMenu));
            menuOwnVO.setPId(systemMenu.getPId());
            menuOwnVO.setHidden("1".equals(systemMenu.getVisible()));
            menuOwnVO.setQuery(systemMenu.getQuery());

            menuOwnVO.setRedirect(systemMenu.getIsFrame().equals("0") ? systemMenu.getPath() : "noRedirect");
            menuOwnVO.getMeta().put("title", systemMenu.getName());
            menuOwnVO.getMeta().put("icon", systemMenu.getIcon());
            menuOwnVO.getMeta().put("noCache", systemMenu.getIsCache().equals("0") ? false : true);
            menuOwnVO.getMeta().put("link", StringUtils.ishttp(systemMenu.getPath()) ? systemMenu.getPath() : null);
            ownMenus.add(menuOwnVO);
        }
        // 转成树
        List<MenuOwnVO> ownTrees = new ArrayList<>();
        for (MenuOwnVO menuOwnVO : ownMenus) {
            if (menuOwnVO.getPId().equals(0l)) {
                MenuOwnVO children = findChildren(ownMenus, menuOwnVO);
                ownTrees.add(children);
            }
        }
        return ownTrees;
    }

    /**
     * 查找子
     *
     * @param lists
     * @param rootMenu
     * @return T
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/24 09:21:28
     */
    private <T extends MenuTreeVO> T findChildren(List<T> lists, T rootMenu) {
        for (T menu : lists) {
            if (rootMenu.getId().equals(menu.getPId())) {
                rootMenu.getChildren().add(findChildren(lists, menu));
            }
        }
        return rootMenu;
    }

    /**
     * 查找子
     *
     * @param lists
     * @param rootMenu
     * @return T
     * @throws
     * @version 1.0.0
     * @author luwc
     * @time 2023/5/24 09:21:28
     */
    private <T extends MenuOwnVO> T findChildren(List<T> lists, T rootMenu) {
        for (T menu : lists) {
            if (rootMenu.getId().equals(menu.getPId())) {
                rootMenu.getChildren().add(findChildren(lists, menu));
            }
        }
        return rootMenu;
    }

    /**
     * 获取路由名称
     *
     * @param menu 菜单信息
     * @return 路由名称
     */
    private String getRouteName(SystemMenu menu) {
        String routerName = StringUtils.capitalize(menu.getPath());
        // 非外链并且是一级目录（类型为目录）
        if (menu.getPId().intValue() == 0 && "C".equals(menu.getMenuType())
                && menu.getIsFrame().equals("1")) {
            routerName = StringUtils.EMPTY;
        }
        return routerName;
    }

    /**
     * 获取路由地址
     *
     * @param menu 菜单信息
     * @return 路由地址
     */
    private String getRouterPath(SystemMenu menu) {
        String routerPath = menu.getPath();
        // 内链打开外网方式
        if (menu.getPId().intValue() != 0 && menu.getIsFrame().equals("1") && StringUtils.ishttp(menu.getPath())) {
            routerPath = StringUtils.replaceEach(routerPath, new String[]{"http://", "https://", "www.", "."},
                    new String[]{"", "", "", "/"});
        }
        // 非外链并且是一级目录（类型为目录）
        if (0 == menu.getPId().intValue() && "M".equals(menu.getMenuType())
                && menu.getIsFrame().equals("1")) {
            routerPath = "/" + menu.getPath();
        }
        // 非外链并且是一级目录（类型为菜单）
        else if (menu.getPId().intValue() == 0 && "C".equals(menu.getMenuType())
                && menu.getIsFrame().equals("1")) {
            routerPath = "/";
        }
        return routerPath;
    }

    /**
     * 获取组件信息
     *
     * @param menu 菜单信息
     * @return 组件信息
     */
    private String getComponent(SystemMenu menu) {
        String component = "Layout";
        if (StringUtils.isNotEmpty(menu.getComponent()) && !(menu.getPId().intValue() == 0 && "C".equals(menu.getMenuType())
                && menu.getIsFrame().equals("1"))) {
            component = menu.getComponent();
        } else if (StringUtils.isEmpty(menu.getComponent()) && menu.getPId().intValue() != 0 && menu.getIsFrame().equals("1") && StringUtils.ishttp(menu.getPath())) {
            component = "InnerLink";
        } else if (StringUtils.isEmpty(menu.getComponent()) && (menu.getPId().intValue() != 0 && "M".equals(menu.getMenuType()))) {
            component = "ParentView";
        }
        return component;
    }
}




